package ru.amse.tsyganov.jumleditor.graphicaleditor;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Rectangle;

import ru.amse.tsyganov.jumleditor.model.common.Edge;
import ru.amse.tsyganov.jumleditor.model.common.GraphModel;
import ru.amse.tsyganov.jumleditor.model.common.State;
import ru.amse.tsyganov.jumleditor.view.common.EdgeView;
import ru.amse.tsyganov.jumleditor.view.common.StateView;
import ru.amse.tsyganov.jumleditor.view.preferences.Colors;
import ru.amse.tsyganov.jumleditor.view.preferences.Cursors;

/*package*/ class AreaSelectionMode extends EditorMode {
	
	private final GraphicalEditor graphicalEditor;
	
	private Rectangle selectingRectangle;
	
	private Rectangle selectingRectangle2;
	
	private final Set<StateView<? extends State>> initiallySelectedStates =
		new HashSet<StateView<? extends State>>();
	
	private final Set<EdgeView<? extends Edge>> initiallySelectedTransitions =
		new HashSet<EdgeView<? extends Edge>>();
	
	public AreaSelectionMode(GraphicalEditor graphicalEditor) {
		if (graphicalEditor == null) {
			throw new IllegalArgumentException();
		}
		this.graphicalEditor = graphicalEditor;
	}
	
	@Override
	public void initState() {
		graphicalEditor.getCanvas().setCursor(
				Cursors.getCursorCross());
		
		graphicalEditor.getActivityGraphView().setPaintConnectionPoints(false);
		
		selectingRectangle = null;
		selectingRectangle2 = null;
		graphicalEditor.getCanvas().redraw();
	}

	@Override
	public void keyPressed(KeyEvent e) {
	}

	@Override
	public void keyReleased(KeyEvent e) {
	}

	@Override
	public void mouseDoubleClick(MouseEvent e) {
	}

	@Override
	public void mouseDown(MouseEvent e) {
		initiallySelectedStates.clear();
		initiallySelectedTransitions.clear();
		
		initiallySelectedStates.addAll(graphicalEditor.
			getActivityGraphView().getSelectedItems().
				getSelectedStates());
		
		initiallySelectedTransitions.addAll(graphicalEditor.
			getActivityGraphView().getSelectedItems().
				getSelectedTransitions());
		
		selectingRectangle = new Rectangle(e.x, e.y, 0, 0);
		selectingRectangle2 = selectingRectangle;
	}

	@Override
	public void mouseMove(MouseEvent e) {
		if (selectingRectangle != null) {
			selectingRectangle.width = e.x - selectingRectangle.x;
			selectingRectangle.height = e.y - selectingRectangle.y;
			
			int w;
			int h;
			int x;
			int y;
			if (selectingRectangle.width > 0) {
				w = selectingRectangle.width;
				x = selectingRectangle.x;
			} else {
				w = -selectingRectangle.width;
				x = selectingRectangle.x - w;
			}
			if (selectingRectangle.height > 0) {
				h = selectingRectangle.height;
				y = selectingRectangle.y;
			} else {
				h = -selectingRectangle.height;
				y = selectingRectangle.y - h;
			}
			selectingRectangle2 = new Rectangle(x, y, w - 1, h - 1);
			
			graphicalEditor.getActivityGraphView().
				getSelectedItems().selectedStatesClear();
			
			graphicalEditor.getActivityGraphView().
				getSelectedItems().selectedTransitionsClear();
			
			graphicalEditor.getActivityGraphView().getSelectedItems().
				addAllStates(initiallySelectedStates);
			
			graphicalEditor.getActivityGraphView().getSelectedItems().
				addAllTransitions(initiallySelectedTransitions);
			
			GraphModel graph = graphicalEditor.
				getActivityGraphView().getModel();
			
			for (State s : graph.getContents()) {
				StateView<? extends State> stateView = graphicalEditor
						.getActivityGraphView().getModelViewMap()
						.getStatesMap().get(s);

				if (stateView.getRectangle().intersects(selectingRectangle2)) {
					graphicalEditor.getActivityGraphView().getSelectedItems()
							.selectedStatesAdd(stateView);
				}

				for (Edge t : s.getStateVertex().getOutgoing()) {
					EdgeView<? extends Edge> transitionView = graphicalEditor
							.getActivityGraphView().getModelViewMap()
							.getEdgesMap().get(t);

					if (selectingRectangle2.contains(transitionView
							.getStartPoint())
							|| selectingRectangle2.contains(transitionView
									.getEndPoint())) {

						graphicalEditor.getActivityGraphView()
								.getSelectedItems().selectedTransitionsAdd(
										transitionView);
					}
				}
			}
		}
	}

	@Override
	public void mouseUp(MouseEvent e) {
		graphicalEditor.setEditorMode(
				graphicalEditor.getSelectionMode());
	}

	@Override
	public void paintControl(PaintEvent e, Coordinates coordinates) {
		if (selectingRectangle2 != null) {
			e.gc.setForeground(Colors.getBlackColor());
			e.gc.setLineStyle(SWT.LINE_DOT);
			e.gc.drawRectangle(
					coordinates.fromModelXToScreenX(selectingRectangle2.x),
					coordinates.fromModelYToScreenY(selectingRectangle2.y),
					selectingRectangle2.width, selectingRectangle2.height);
			e.gc.setLineStyle(SWT.LINE_SOLID);
		}
	}
}
